package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.constant.Constants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.VoiceApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Voice;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.VoiceVo;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@Service
@Slf4j
public class VoiceService {

    @DubboReference
    private VoiceApi voiceApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private FastFileStorageClient fastDFSClient;
    /**
     * 桃花传音-接收语音
     * @return
     */
    public VoiceVo putVoice() {

        Long userId = UserHolder.getUserId();   // 当前登录用户id
        // 查询redis中 该用户接收语音的次数 < 3 提示今日次数已经用光
        String timeKey = Constants.VOICE_RECEIVE_LEFT + userId;

        // 设置该用户存入redis中的已读的语音信息id
        String readKey = Constants.USER_READ_VOICE + userId;

        // 获取用户今日接收语音次数
        String timeSize = stringRedisTemplate.opsForValue().get(timeKey);

        if(StringUtils.isEmpty(timeSize)){
            stringRedisTemplate.opsForValue().set(timeKey,"3");
            timeSize = "3";
        }
        // 如果次数小于0 则抛出，次数已用尽异常
        if(Integer.parseInt(timeSize) <= 0){
            throw new TanHuaException(ErrorResult.timeOut());
        }

        // 得到userInfo用户信息
        UserInfo userInfo = userInfoApi.getUserInfo(userId);    // 当前用户对象信息

        // 获取redis中存在用户已读的语音消息
        List readList = stringRedisTemplate.opsForList().range(readKey, 0, -1);

        // 根据用户信息，随机得到一条语音信息
        Voice voice = voiceApi.findOne(userInfo,readList);

        // 通过这条件语音的发布者的id查询该用户信息
        UserInfo info = null;
        if(voice != null){
            info = userInfoApi.getUserInfo(voice.getUserId());
        }

        // 定义一个VoiceVo集合，接收所有的语音信息
        VoiceVo voiceVo = null;
        if(voice != null) {
            voiceVo = VoiceVo.init(info, voice);
        }

        // 将当前用户接收到的这条语音消息id存入redis中，以便下次不再收到这条语音
        stringRedisTemplate.opsForList().leftPush(readKey,voice.getId().toString());

        // 当用户每次接收完语音信息后，将它的次数-1
        Long remainingTimes = stringRedisTemplate.opsForValue().decrement(timeKey);
        voiceVo.setRemainingTimes(remainingTimes.intValue());

        return voiceVo;
    }


    // 定时更新redis中用户接收语音次数
    public void updTimeSize(){

        // 获取所有的用户信息
        List<UserInfo> userInfos = userInfoApi.findAll();
        // 通过定时任务，每天将所有的用户接收语音次数重置为3次
        if(CollectionUtils.isNotEmpty(userInfos)){
            for (UserInfo userInfo : userInfos) {
                String timeKey = Constants.VOICE_RECEIVE_LEFT + userInfo.getId();
                stringRedisTemplate.opsForValue().set(timeKey,"3");
            }
        }
    }

    /**
     * 桃花传音:发送语音
     * @param soundFile
     */
    public void save(MultipartFile soundFile) {
        //获取发送者id
        Long userId = UserHolder.getUserId();

        //查询redis中 该用户发送语音的次数<3,提示报错
        String timeKey = Constants.VOICE_SEND_LEFT + userId;

        //设置今日能发送的语音次数为3条
        String timeSize = stringRedisTemplate.opsForValue().get(timeKey);

        if(StringUtils.isEmpty(timeSize)){
            stringRedisTemplate.opsForValue().set(timeKey,"3");
            timeSize = "3";
        }

        if (Integer.valueOf(timeSize)<=0){
            throw new TanHuaException("每日上传次数已达上限");
        }


        //获得登录用户id的性别
        UserInfo userInfo = userInfoApi.getUserInfo(userId);
        String gender = userInfo.getGender(); //性别


        //获取语音文件, 后缀名
        String fileName = soundFile.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);


        //上传语音到fast dfs
        StorePath storePath = null;
        try {
            storePath = fastDFSClient.uploadFile(soundFile.getInputStream(), soundFile.getSize(), suffix,null);
        } catch (IOException e) {
            //e.printStackTrace();
            throw new TanHuaException("上传语音文件失败~");
        }
        //获取语音地址
        String voiceUrl= fdfsWebServer.getWebServerUrl()+storePath.getFullPath();

         //每次发送语音减1次可发送次数
        stringRedisTemplate.opsForValue().decrement(timeKey);

        voiceApi.add(userId,voiceUrl,gender);
    }
    // 定时更新redis中用户语音次数
    public void UploadVoice(){
        // 获取所有的用户信息
        List<UserInfo> userInfos = userInfoApi.findAll();
        // 通过定时任务，每天将所有的用户发送语音次数重置为3次
        if(CollectionUtils.isNotEmpty(userInfos)){
            for (UserInfo userInfo : userInfos) {
                String timeKey = Constants.VOICE_SEND_LEFT + userInfo.getId();
                stringRedisTemplate.opsForValue().set(timeKey,"3");
            }
        }
    }
}

